package reflection;

/**
 * 获取Class对象
 */
public class GetClass_ {

    public static void main(String[] args) throws Exception {
        /*
            1)前提：已知一个类的全类名，且该类在类路径下，可通过Class类的静态方法forName()获取，
              可能抛出ClassNotFoundException，实例： Class cls1 = Class.forName("reflection.Cat");
              应用场景：多用于配置文件，读取类全路径，加载类
            2)若已知具体的类，通过类的class获取，该方式最为安全可靠，程序性能最高
              Class cls2 = Cat.class;
              应用场景：多用于参数传递，比如通过反射得到对应构造器对象
            3)已知某个类的实例，调用该实例的getClass()方法获取Class对象
            4)通过类加载器获取Class对象
            5)基本数据类型(int char boolean float double byte long short)
            6)基本数据类型对应的包装类，可以通过.Type得到Class类对象
         */

        //1.已知全类名
        String classAllPath = "reflection.Car";
        Class cls1 = Class.forName(classAllPath);
        System.out.println(cls1);

        //2.类名.class，多用于参数传递
        Class cls2 = Car.class;
        System.out.println(cls2);

        //3.对象.getClass()
        Car car = new Car();
        Class cls3 = car.getClass();
        System.out.println(cls3);

        //4.通过类加载器来获取到类的Class对象
        //1)先得到类加载器
        ClassLoader classLoader = car.getClass().getClassLoader();
        //2)通过类加载得到Class对象
        Class cls4 = classLoader.loadClass(classAllPath);
        System.out.println(cls4);

        //cls cls2 cls3 cls4是同一个对象
        System.out.println(cls1.hashCode());
        System.out.println(cls2.hashCode());
        System.out.println(cls3.hashCode());
        System.out.println(cls4.hashCode());

        //5.基本数据类型，可以直接.Class获取 Class对象
        Class<Integer> integerClass = int.class;
        System.out.println(integerClass);

        //6.基本数据类型对应的包装类，可以通过.Type得到Class类对象
        Class<Integer> c = Integer.TYPE;
        System.out.println(c);
    }
}
